package com.start.form.engine.core.storage;


import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.start.common.dataRule.StartQueryWrapper;
import com.start.common.exceptions.StartBusException;
import com.start.common.std.StartBaseSingleton;
import com.start.common.std.StartSingletonFactory;
import com.start.common.tools.SpringContextTools;
import com.start.form.engine.core.StartFormEngine;
import com.start.form.engine.core.TableDataEngineService;
import com.start.form.engine.core.TableEngineService;
import com.start.form.engine.core.entity.StartFormConfig;
import com.start.form.engine.core.tools.StartAvueColTools;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

import static com.start.form.engine.core.StartFormEngineConstant.FormBaseColumns.*;


public class StartAvueDynamicStoreImpl extends StartBaseSingleton<StartAvueDynamicStoreImpl> implements StartAvueDynamicStore {

    private static StartFormEngine startFormEngine;


    public static StartAvueDynamicStoreImpl getInstance() {
        return StartSingletonFactory.get(StartAvueDynamicStoreImpl.class);
    }

    @Override
    public void init() {
        startFormEngine = SpringContextTools.getBean(StartFormEngine.class);
    }

    /**
     * 保存子表数据
     *
     * @param mainTableConfig 主表配置
     * @param mainDataId      主表数据id
     * @param data            需要保存的数据
     */
    public void save(StartFormConfig mainTableConfig, String mainDataId, JSONObject data) {
        if (StringUtils.isAllBlank(mainDataId)) {
            throw new StartBusException("主表数据不能为空");
        }
        if (data == null) {
            return;
        }
        handlerAvueDynamic(mainTableConfig, (dynamicTableConfig, dynamic, prop) -> {
            JSONArray dynamicData = data.getJSONArray(prop);
            saveToDynamicForm(dynamicTableConfig, mainDataId, dynamicData);
        });

    }

    private void saveToDynamicForm(StartFormConfig dynamicFormConfig, String mainDataId, JSONArray data) {
        if (data == null || data.isEmpty()) {
            return;
        }
        for (int i = 0; i < data.size(); i++) {
            JSONObject jsonObject = data.getJSONObject(i);
            saveToDynamicForm(dynamicFormConfig, mainDataId, jsonObject);
        }
    }

    private void saveToDynamicForm(StartFormConfig dynamicFormConfig, String mainDataId, JSONObject data) {
        TableDataEngineService tableDataEngineService = startFormEngine.getTableDataEngineService(dynamicFormConfig);
        data.put(COLUMN_MAIN_TABLE_ID, mainDataId);
        tableDataEngineService.save(dynamicFormConfig, data);
    }


    /**
     * 删除数据
     *
     * @param mainTableConfig 主表配置
     * @param mainDataId      主表数据id
     */
    @Override
    public void remove(StartFormConfig mainTableConfig, String mainDataId) {
        if (StringUtils.isAllBlank(mainDataId)) {
            throw new StartBusException("主表数据不能为空");
        }
        StartQueryWrapper startQueryWrapper = new StartQueryWrapper();
        startQueryWrapper.eq(COLUMN_MAIN_TABLE_ID, mainDataId);
        handlerAvueDynamic(mainTableConfig, (dynamicTableConfig, dynamic, prop) -> {
            dynamicTableRemove(dynamicTableConfig, startQueryWrapper);
        });

    }

    private void dynamicTableRemove(StartFormConfig dynamicTableConfig, StartQueryWrapper queryWrapper) {
        TableDataEngineService tableDataEngineService = startFormEngine.getTableDataEngineService(dynamicTableConfig);
        tableDataEngineService.remove(dynamicTableConfig, queryWrapper);
    }

    /**
     * 修改数据
     *
     * @param mainTableConfig 主表配置
     * @param mainDataId      主表数据id
     * @param data            子表需要更新的数据
     */
    @Override
    public void update(StartFormConfig mainTableConfig, String mainDataId, JSONObject data) {
        if (StringUtils.isAllBlank(mainDataId)) {
            throw new StartBusException("主表数据不能为空");
        }

        handlerAvueDynamic(mainTableConfig, (dynamicTableConfig, dynamic, prop) -> {
            JSONArray dynamicData = data.getJSONArray(prop);
            if (dynamicData == null || dynamicData.isEmpty()) {
                return;
            }
            dynamicTableUpdate(dynamicTableConfig, mainDataId, dynamicData);
        });
    }

    private void dynamicTableUpdate(StartFormConfig dynamicTableConfig, String mainDataId, JSONArray dynamicTableData) {
        if (dynamicTableData == null || dynamicTableData.isEmpty()) return;
        StartQueryWrapper startQueryWrapper = new StartQueryWrapper();
        startQueryWrapper.eq(COLUMN_MAIN_TABLE_ID, mainDataId);
        dynamicTableRemove(dynamicTableConfig, startQueryWrapper);
        saveToDynamicForm(dynamicTableConfig, mainDataId, dynamicTableData);
    }

    /**
     * 查询数据
     *
     * @param mainTableConfig 主表配置
     * @param mainData        主表数据id
     * @return
     */
    @Override
    public void handlerDynamicSelect(StartFormConfig mainTableConfig, JSONObject mainData) {
        if (mainData == null || mainData.isEmpty()) {
            return;
        }
        StartQueryWrapper startQueryWrapper = new StartQueryWrapper();
        startQueryWrapper.eq(COLUMN_MAIN_TABLE_ID, mainData.getString(COLUMN_PK_NAME));
        startQueryWrapper.orderByAsc(COLUMN_CREATE_TIME);
        handlerAvueDynamic(mainTableConfig, (dynamicTableConfig, dynamic, prop) -> {
            TableDataEngineService tableDataEngineService = startFormEngine.getTableDataEngineService(dynamicTableConfig);
            List<JSONObject> list = tableDataEngineService.list(dynamicTableConfig, startQueryWrapper);
            mainData.put(prop, list);
        });
    }


    @Override
    public void syncDynamicTable(StartFormConfig mainTableConfig) {
        handlerAvueDynamic(mainTableConfig, (dynamicTableConfig, dynamic, prop) -> {
            TableEngineService tableEngineService = startFormEngine.getTableEngineService(dynamicTableConfig);
            tableEngineService.synchronizationTable(dynamicTableConfig);

        });

    }

    /**
     * 处理表单总子表单创建同步逻辑
     *
     * @param mainFormConfig
     */
    private void handlerAvueDynamic(StartFormConfig mainFormConfig, StartAvueDynamicStore.handlerDynamicTable handlerDynamicTable) {
        List<JSONObject> tableAvueDynamic = StartAvueColTools.getTableAvueDynamic(mainFormConfig);
        if (tableAvueDynamic == null || tableAvueDynamic.isEmpty()) return;
        for (JSONObject dynamic : tableAvueDynamic) {
            JSONObject children = dynamic.getJSONObject("children");
            if (!children.containsKey("column")) {
                continue;
            }
            if (children.getJSONArray("column").isEmpty()) {
                continue;
            }

            StartFormConfig dynamicFormConfig = StartAvueColTools.getAvueDynamicFormConfig(mainFormConfig, dynamic);
            handlerDynamicTable.handler(dynamicFormConfig, dynamic, dynamic.getString("prop"));
        }
    }
}
